<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>  
  <head>    
    <title>OpenGL Utility Toolkit (GLUT)</title>    
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <link href="../../styles.css" rel="stylesheet">
    <link rel="icon" href="../../images/icon.png">
	</head>
	<body>
		<div id="top">
      <h1>OpenGL Utility Toolkit (GLUT)</h1> 
		</div>     
    <div id="main">
      <h2>Contenido</h2>
      <div class="contents">
        <ol>
          <li><a href="#req">Requisitos</a></li>
          <li><a href="#intro">Introducción</a></li>
          <li><a href="#setup">Configuración</a></li>
          <li><a href="#defs">Definiciones</a></li>
          <li><a href="#first-prog">El primer programa</a></li>
          <li><a href="#draw-area">El &aacute;rea de dibujo</a></li>
          <li><a href="#window">La ventana</a></li>
          <li><a href="#menu">El menú</a></li>
          <li><a href="#callback">Funciones ejecutadas por interacción</a></li>
          <!-- Color Index Colormap, State Retrieval, Font Rendering, Geometric Object Rendering? -->
          <li><a href="#deprecated">Funciones obsoletas</a></li>
          <li><a href="#refs">Referencias</a></li>
        </ol>
      </div>
      <h2 id="req">Requisitos</h2>
      <div class="contents">
        <ul>
          <li><a href="https://archive.org/details/c-programming-a-modern-approach-2nd-ed-c-89-c-99-king-by/">Saber programar en C</a>.</li>
        </ul>
      </div>
      <h2 id="intro">Introducción</h2>
      <div class="contents">        
        <p>El <b>K</b>it de <b>H</b>erramientas de <b>U</b>tilidad Open<b>GL</b> (<b>KHUGL</b>) u Open<b>GL</b> <b>U</b>tility <b>T</b>oolkit (<b>GLUT</b>) es una librería en C que proporciona funciones sencillas y útiles para el manejo de <b>ventanas</b>, en el sistema operativo, en las que luego se podrán ejecutar aplicaciones construidas con la librería de <b>OpenGL</b>.</p>
        <br>
        <p><b>GLUT</b> es básicamente un creador de "hojas blancas" en las cuales se puede luego "dibujar" usando OpenGL. Se puede usar en Windows, Linux y MacOS pero lo que escribo solo contenpla su uso en Linux (con el compilador <b>GCC</b>).</p>
        <br>
        <p>En este escrito se van a usar las funciones de GLUT y, para nuevas funciones, la implementación "Libre" de GLUT (ya que la versión original era de código cerrado) llamada <b>FreeGLUT</b>. FreeGLUT es compatible con programas hechos para GLUT por lo que se puede usar directamente para todos los ejemplos aqui descritos. La página web oficial del proyecto de FreeGLUT se puede conseguir en las <a href="#refs">referencias</a>. Dicha página proporciona el código fuente de FreeGLUT para ser compilado y da información sobre como instalar paquetes ya compilados de FreeGLUT para cada sistema operativo.</p>
      </div>
      <h2 id="setup">Configuración</h2>
      <div class="contents">
        <p>Como se mencionó anteriormente, en esta página se considera el uso de FreeGLUT bajo Linux (basado en Debian) dada la simplicidad en la configuración. Para cualquier distribución de Linux basada en Debian <i>lo más probable</i> es que las librerías ya esten instaladas en tu sistema, si no, puedes instalarlas a través de <b>APT</b> con el siguiente comando:</p>
        <div class="code_block">
          <p>sudo apt install libglut-dev freeglut3-dev</p>
        </div>
        <p>En caso de que lo anterior no funcione, tienes que investigar cuales son los paquetes a instalar o puedes <a href="https://freeglut.sourceforge.net/docs/install.php">compilar FreeGLUT tu mismo</a> y usarlo para seguir este escrito. Para <b>Windows</b> se menciona que se puede usar <b>Cygwin</b> o <b>MSYS</b> para obtener/usar la librería, pero no estoy seguro de como funciona el asunto (puede que escriba luego acerca de ello).</p>
      </div>
      <h2 id="defs">Definiciones</h2>
      <div class="contents">
        <p>GLUT posee varios <b>objetos</b>, estos objetos pueden ser creados, inicializados, editados y eliminados a través de funciones asociadas a ellos. El objeto principal de GLUT es la <b>ventana</b> y es el elemento principal con el cual se va a trabajar.</p>
        <br>        
        <p>En un programa que usa GLUT se pueden crear multiples objetos de un mismo tipo, pero sólo uno de ellos estará disponible para ser editado a la vez. A este objeto se le denomina <b>el objeto actual</b> y representa símbolicamente <i>el objeto actualmente seleccionado</i>. La <i>selección</i> puede ocurrir implícitamente (cuando se crea dicho objeto por ejemplo) o explícitamente (a través de la ejecución manual de la función de selección asociada). Cuando un objeto está seleccionado, todas las funciones que se ejecuten relacionadas al tipo de objeto del objeto seleccionado van a operar sobre este objeto seleccionado y no sobre otros objetos. Solamente se actuará sobre otro objeto (del mismo tipo) cuando se seleccione, mediante la funcion de selección necesaria, al siguiente objeto con el que se desee trabajar a través de la referencia que se tenga del mismo.</p>
      </div>
      <h2 id="first-prog">El primer programa</h2>
      <div class="contents">
        <p>Primero que todo, hay que hacer un primer programa en el que se encuentre el código mínimo necesario para saber si GLUT (o la implementación de GLUT de FreeGLUT) esta instalado correctamente.</p>
        <br>
        <p>En un archivo de C (<code>test.c</code> por ejemplo) copia y pega el siguiente código:</p>
        <div class="code_block">
<pre>
#include &lt;GL/glut.h&gt;
  
int main(void)
{
  return 0;
}
</pre>
        </div>
        <br>
        <p>Luego, compila el programa con GCC usando el siguiente comando:</p>
        <div class="code_block"><p>gcc test.c -lglut</p></div>
        <br>
        <p><b>NOTA:</b> <code>-lglut</code> le indica a GCC que enlace la librer&iacute;a GLUT para conseguir las implementaciones de las funciones de GLUT que uno est&eacute; usando en su c&oacute;digo (<code>-lglut</code> equivale a decir <b>link GLUT</b>)</p>        
        <br>
        <p>Si el compilador no muestra errores/advertencias entonces la libreria de GLUT es accesible y se puede empezar a desarrolar programas con ella.</p>
        <br>
        <p>Ahora, el primer programa real de GLUT ser&aacute; el siguiente:</p>
        <div class="code_block">
<pre>
#include &lt;GL/glut.h&gt;
  
void some_func(void)
{
  return;
}

int main(int argc, char ** argv)
{
  glutInit(&amp;argc, argv);
  int window1 = glutCreateWindow(NULL);
  glutDisplayFunc(some_func);
  glutMainLoop();
  return 0;
}
</pre>
        </div>
        <br>
        <p>Al compilar este programa y ejecutarlo (si todo sale bien) deber&iacute;as ver algo como lo mostrado en la siguiente imagen.</p>
        <img src="../../images/glut1/first-prog1.png" alt="Image could not be loaded.">
        <p class="idtext">Fig. 1: Ventana creada por GLUT con "lo que sea" de contenido.</p>
        <p>Vamos a ir paso por paso indicado lo que se necesita saber de este programa:</p>
        <ul>
          <li>Todo lo que se muestra en este programa es lo m&iacute;nimo necesario para crear la &uacute;nica ventana que se muestra en la imagen.</li>
          <li>Como no nos importa el contenido de la ventana, el mismo se compone de lo que sea que se encuentre en la regi&oacute;n asociada de la pantalla al momento en que aparezca la ventana. Arrastr&eacute; una ventana del explorador de archivos encima de la ventana de GLUT y, en mi caso, queda ese "efecto de barrido" que dejan los programas cuando se atascan/funcionan lento.</li>
          <li>
            <p>El c&oacute;digo fuente del programa tiene varias funciones desconocidas:</p>
            <ul>
              <li>
                <p><code>void glutInit(int * argcp, char ** argv)</code>: funci&oacute;n que se tiene que llamar <b>siempre</b> al inicio de un programa GLUT. Se encarga de inicializar dicha librer&iacute;a y necesita de los par&aacute;metros de la funci&oacute;n <code>main</code> cuando se quieren pasar datos de entrada de la terminal. Estos parametros son pasados a la funcion para <a href="https://www.opengl.org/resources/libraries/glut/spec3/node10.html">leer las posibles entradas por terminal que puedan modificar el funcionamiento inicial</a> del programa GLUT.</p>
              </li>
              <li>
                <p><code>int glutCreateWindow(char * name)</code>: crea un objeto tipo ventana que tendr&aacute; de nombre en el borde superior la cadena de caracteres ASCII apuntada por <code>name</code>. La funci&oacute;n devuelve un n&uacute;mero entero (que empieza en 1) que representa a la ventana (es la identificaci&oacute;n de la ventana creada). Esta funci&oacute;n impl&iacute;citamente establece la ventana creada como la ventana actual.</p>
              </li>
              <li>
                <p><code>void glutDisplayFunc(void (* func)(void))</code>: esta funci&oacute;n establece la funci&oacute;n, para la ventana actual, que se va a llamar cuando GLUT considere que la ventana necesita ser redibujada/refrescada. Es obligatorio el uso de esta funci&oacute;n despues de haber creado una ventana. En otras palabras, es una funci&oacute;n que permite establecer la funci&oacute;n de "actualizaci&oacute;n" de una ventana.</p>
              </li>
              <li>
                <p><code>void glutMainLoop(void)</code>: esta funci&oacute;n se encarga de evitar que llegue el fin del programa de C. B&aacute;sicamente es una funci&oacute;n que se ejecuta eternamente hasta que el programa de GLUT finaliza (se cierra la ventana en el boton de cerrado usual de las ventana) y se encarga de ejecutar todas las funciones en segundo plano que se requieren para cambiar los estados de los objetos creados en GLUT. Tiene que aparecer como m&aacute;ximo 1 vez.</p>
              </li>
            </ul>
          </li>
        </ul>
        <br>
        <p>Con todo lo anterior dicho, falta tambien informaci&oacute;n acerca de &iquest;Donde van a empezar a salir las ventanas en la pantalla? y &iquest;Qu&eacute; dimensiones iniciales tendr&aacute;n las ventanas? Bueno, esas son condiciones iniciales que pueden establecerse antes de crear alguna ventana con <code>glutCreateWindow</code>. Si las funciones no se llaman, GLUT pondr&aacute; el valor que le parezca. Adicionalmente, las funciones pueden llamarse m&aacute;s de una vez para "sobreescribir" estos valores iniciales.</p>
        <ul>
          <li>
            <p><code>void glutInitWindowPosition(int x, int y)</code>: establece la posici&oacute;n inicial de todas las ventanas creadas con <code>glutCreateWindow</code> en pixeles. La posici&oacute;n <code>(x, y)</code> es con respecto a la esquina superior izquierda de la pantalla. +X es hacia la derecha +Y es hacia abajo.</p>
          </li>
          <li>
            <p><code>void glutInitWindowSize(int width, int height)</code>: establece las dimensiones iniciales de todas las ventanas creadas con <code>glutCreateWindow</code> en pixeles.</p>
          </li>
        </ul>
        <a href="../../images/glut1/first-prog2.png"><img src="../../images/glut1/first-prog2.png" alt="Image could not be loaded."></a>
        <p class="idtext">Fig. 2: ejemplos del uso de <code>glutInitWindowPosition</code> y <code>glutInitWindowSize</code>.</p>
        <br>
        <p>En la implementaci&oacute;n de FreeGLUT se mencionan ciertas diferencias respecto a GLUT en relaci&oacute;n a la interpretaci&oacute;n de estos valores. Lo que sucede se puede explicar a trav&eacute;s de la siguiente imagen y <a href="https://freeglut.sourceforge.net/docs/api.php#Conventions">es explicado en este enlace</a>.</p>
        <img src="../../images/glut1/first-prog3.png" alt="Image could not be loaded.">
        <p class="idtext">Fig. 3: Ventana real en la pantalla.</p>
        <p><i>En FreeGLUT</i>:</p>
        <ul>
          <li>Cuando se crea una ventana con coordenadas <code>(x, y)</code> y tama&ntilde;o <code>(ancho, alto)</code> las coordenadas <code>(x, y)</code> corresponden a las coordenadas de la ventana real (punto azul) y las dimensiones <code>(ancho, alto)</code> corresponden a las dimensiones del &aacute;rea de dibujo (que se localiza en el punto rojo).</li>
          <li>Cuando se pide la posici&oacute;n <code>(x, y)</code> y dimensi&oacute;n <code>(ancho, alto)</code> de una ventana (a trav&eacute;s de la funci&oacute;n <code>glutGet</code> cuando ya se han creado las ventanas, a explicar luego), la posici&oacute;n y dimensiones devueltas por FreeGLUT son &uacute;nicamente del &aacute;rea de dibujo.</li>
        </ul>
        <br>
        <p>Con eso claro, vamos a ver a la funci&oacute;n <code>glutGet</code> de forma superficial.</p>
        <ul>
          <li>
            <p><code>int glutGet(GLenum state)</code>: <code>state</code> es un valor de enumeraci&oacute;n que puede representar distintas propiedades de los objetos de GLUT, al pasarselo a la funci&oacute;n, esta devuelve el n&uacute;mero entero que representa a esta variable. Algunos posibles valores a pasar a <code>glutGet</code> son los siguientes:</p>
            <ul>
              <li><code>GLUT_WINDOW_X</code>: posici&oacute;n X de la ventana en pixeles.</li>
              <li><code>GLUT_WINDOW_Y</code>: posici&oacute;n Y de la ventana en pixeles.</li>
              <li><code>GLUT_WINDOW_WIDTH</code>: ancho de la ventana en pixeles.</li>
              <li><code>GLUT_WINDOW_HEIGHT</code>: alto de la ventana en pixeles.</li>
            </ul>
          </li>
        </ul>
        <p>El resto de los posibles valores de enumeraci&oacute;n que pueden pasarse a la funci&oacute;n se muestran <a href="https://www.opengl.org/resources/libraries/glut/spec3/node70.html">aqu&iacute;</a> (GLUT) y <a href="https://freeglut.sourceforge.net/docs/api.php#StateSetting">aqu&iacute;</a> (FreeGLUT).</p>
        <br>
        <img src="../../images/glut1/first-prog4.png" alt="Image could not be loaded.">
        <p class="idtext">Fig. 4: Ejemplo del uso de <code>glutGet</code> para obtener la posici&oacute;n y tama&ntilde;o de una ventana.</p>
      </div>
      <h2 id="draw-area">El &aacute;rea de dibujo</h2>
      <div class="contents">
        <p>La computaci&oacute;n gr&aacute;fica es un &aacute;rea cuya naturaleza es la de llevar a cabo muchas operaciones ocurriendo en paralelo, ya que paa generar una imagen hay que considerar muchas variables (color, iluminaci&oacute;n, perspectiva, etc.). Al final, todas las operaciones devuelven sus resultados, y, al apilarlos unos sobre otros, se genera la imagen final que se muestra en la pantalla del computador. Existe entonces la necesidad de guardar la informaci&oacute;n de cada proceso en algun sitio y ese sitio, en general, es un <b>buffer</b>.</p>
        <br>
        <p>En OpenGL existen varios tipos de bufferes y desde FreeGLUT uno puede decidir que tipo de buffer habilitar en una ventana. Esta informaci&oacute;n se especifica a trav&eacute;s de la funci&oacute;n <code>glutInitDisplayMode</code>.</p>
        <ul>
          <li><code>void glutInitDisplayMode(unsigned int mode)</code>:</li>
        </ul>
        <p>Los bufferes que usar&aacute; ser&aacute;n o GLUT_DOUBLE o GLUT_SINGLE</p>
        <p>Como se dijo en la secci&oacute;n anterior, el &aacute;rea de dibujo es donde se reflejan visualmente los comandos de OpenGL. En este escrito no voy a tocar el como dibujar en OpenGL (principalmente porque no s&eacute; todavia como usarlo >:]) pero para poder continuar con buenos ejemplos en GLUT necesito usar 4 funciones muy elementales que son parte de la librer&iacute;a de OpenGL 1.1:</p>
        <ul>
          <li>glClearColor()</li>
          <li>glClear()</li>
          <li>glFlush()</li>
          <li>glFinish()</li>
        </ul>
      </div>
      <h2 id="window">La ventana</h2>
      <div class="contents">
        <p>La ventana, como se dijo, es el objeto principal de GLUT.</p>
      </div>
      <h2 id="refs">Referencias</h2>
      <div class="contents">
        <ul>
          <li><a href="https://www.opengl.org/resources/libraries/glut/spec3/spec3.html">Página oficial de referencia de GLUT Versión 3</a></li>
          <li><a href="https://freeglut.sourceforge.net/">Página oficial de la librería FreeGLUT</a></li>
          <li><a href="https://www.talisman.org/opengl-1.1/Reference.html">Referencia de OpenGL 1.1</a></li>
        </ul>
      </div>
    </div>
	</body>
</html>
